#ifndef QUERYRESULT_H
#define QUERYRESULT_H
#include <QString>
#include <QDateTime>
#include <QJsonObject>
#include <QDateTime>
#include <QJsonArray>
class QueryResult;
using FromJsonFunc = QueryResult* (*)(const QJsonObject&);

class QueryResult
{
public:

    virtual ~QueryResult() = default;

    // 2. 纯虚函数toJson（子类必须实现，用于序列化时添加类型标识）

    // 3. 静态工厂函数（核心入口：根据JSON自动创建对应子类实例）
    static QueryResult* fromJson(const QJsonObject& json) {
        QString type = json["type"].toString();
        if (type.isEmpty()) {
            qWarning() << "QueryResult::fromJson: 缺少type字段";
            return nullptr;
        }
        // 从注册表中查找对应的子类创建函数
        auto it = s_fromJsonMap.find(type);
        if (it == s_fromJsonMap.end()) {
            qWarning() << "QueryResult::fromJson: 未知类型" << type;
            return nullptr;
        }
        // qDebug()<<4;
        // qDebug()<<json.isEmpty();
        // qDebug()<<json;
        // qDebug()<<json.isEmpty();

        // 调用子类的fromJson创建实例
        return it.value()(json);
    }

    // 4. 静态注册接口（供子类调用，注册自身的fromJson）
    static void registerFromJson(const QString& type, FromJsonFunc func) {
        s_fromJsonMap.insert(type, func);
    }

    // 基类成员（你的原始成员，修正构造函数笔误：FlightId→Id）
    QString Id = "Test";
    QString Source = "Test";
    QString Destination = "Test";
    QDateTime SetOutTime = QDateTime::currentDateTime();
    QDateTime ArriveTime = QDateTime::currentDateTime();

    // 构造函数（默认+带参）
    QueryResult() = default;
    QueryResult(const QueryResult&) = default;
    QueryResult(QString fid, QString src, QString dst, QDateTime set, QDateTime arr)
        : Id(fid), Source(src), Destination(dst), SetOutTime(set), ArriveTime(arr) {}

private:
    // 静态注册表：key=子类类型标识（字符串），value=子类fromJson函数指针
    static QMap<QString, FromJsonFunc> s_fromJsonMap;
};


class FlightResult:public QueryResult{
public:
    QString FirstClassCnt;
    QString EconomyClassCnt;
    QString FirstClassPrice;
    QString EconomyClassPrice;
    static QueryResult* fromJson(const QJsonObject& json){
        FlightResult* res = new FlightResult();
        res->Destination = json["destination"].toString();
        res->Source = json["source"].toString();
        res->SetOutTime = QDateTime::fromString(json["starttime"].toString());
        res->ArriveTime = QDateTime::fromString(json["endtime"].toString());
        QStringList types = json["types"].toString().split(',');
        QStringList cnts = json["cnts"].toString().split(',');
        QStringList prices = json["prices"].toString().split(',');
        int index1 = types.indexOf("FlyFirstClass");
        int index2 = types.indexOf("FlyEconomyClass");
        res->FirstClassCnt = cnts.at(index1);
        res->EconomyClassCnt = cnts.at(index2);
        res->FirstClassPrice = prices.at(index1);
        res->EconomyClassPrice = prices.at(index2);
        res->Id = json["name"].toString();
        return res;
    }
private:
    struct Register {
        Register() {
            QueryResult::registerFromJson("FlightResult", &FlightResult::fromJson);
        }
    };
    static Register s_register;
};

class TrainResult:public QueryResult{
public:

};
class HighSpeedResult:public TrainResult{
public:
    QString FirstClassCnt = "1";
    QString SecondClassCnt = "1";
    QString FirstClassPrice = "1";
    QString SecondClassPrice = "1";
    static QueryResult* fromJson(const QJsonObject& json){
        // qDebug()<<json;
        HighSpeedResult* res = new HighSpeedResult();
        res->Destination = json["destination"].toString();
        res->Source = json["source"].toString();
        res->SetOutTime = QDateTime::fromString(json["starttime"].toString());
        res->ArriveTime = QDateTime::fromString(json["endtime"].toString());
        QStringList types = json["types"].toString().split(',');
        QStringList cnts = json["cnts"].toString().split(',');
        QStringList prices = json["prices"].toString().split(',');
        int index1 = types.indexOf("HighFirstClass");
        int index2 = types.indexOf("HighSecondClass");
        qDebug()<<index1<<" "<<index2;
        // qDebug()<<types;
        // qDebug()<<cnts;
        // qDebug()<<prices;
        if(index1!=-1){
        res->FirstClassCnt = cnts.at(index1);
        res->FirstClassCnt = prices.at(index1);
        }
        if(index2!=-1){
            res->SecondClassCnt = cnts.at(index2);
            res->SecondClassCnt = prices.at(index2);
        }
        res->Id = json["name"].toString();
        return res;
    }
private:
    struct Register{
        Register(){
            QueryResult::registerFromJson("高铁",&HighSpeedResult::fromJson);
        }
    };
    static Register s_register;
};

class QuickTrainResult:public TrainResult{
public:
    QString HardSeatCnt;
    QString SoftBedCnt;
    QString HardBedCnt;
    QString HardSeatPrice;
    QString SoftBedPrice;
    QString HardBedPrice;
    static QueryResult* fromJson(const QJsonObject& json){
        QuickTrainResult* res = new QuickTrainResult();
        res->Destination = json["destination"].toString();
        res->Source = json["source"].toString();
        res->SetOutTime = QDateTime::fromString(json["starttime"].toString());
        res->ArriveTime = QDateTime::fromString(json["endtime"].toString());
        QStringList types = json["types"].toString().split(',');
        QStringList cnts = json["cnts"].toString().split(',');
        QStringList prices = json["prices"].toString().split(',');
        int index1 = types.indexOf("SoftBed");
        int index2 = types.indexOf("HardBed");
        int index4 = types.indexOf("HardSeat");
        if(index1>=0){
        res->SoftBedCnt = cnts.at(index1);
        res->SoftBedPrice = prices.at(index1);
        }
        if(index2>=0){
        res->HardBedCnt = cnts.at(index2);
        res->HardBedPrice = prices.at(index2);
        }
        if(index4>=0){
        res->HardSeatPrice = prices.at(index4);
        res->HardSeatCnt = cnts.at(index4);
        }
        res->Id = json["name"].toString();
        return res;
    }
private:
    struct Register{
        Register(){
            QueryResult::registerFromJson("QuickTrainResult",&QuickTrainResult::fromJson);
        }
    };
    static Register s_register;
};

class BusResult:public QueryResult{
public:
    QString Cnt;
    QString Price;
    static QueryResult* fromJson(const QJsonObject& json){
        BusResult* res = new BusResult();
        res->Destination = json["destination"].toString();
        res->Source = json["source"].toString();
        res->SetOutTime = QDateTime::fromString(json["starttime"].toString());
                          res->ArriveTime = QDateTime::fromString(json["endtime"].toString());
        QStringList types = json["types"].toString().split(',');
        QStringList cnts = json["cnts"].toString().split(',');
        QStringList prices = json["prices"].toString().split(',');
        int index1 = types.indexOf("BusSeat");
        if(index1>=0){
        res->Cnt = cnts.at(index1);
        res->Price = prices.at(index1);
        }
        res->Id = json["name"].toString();
        return res;
    }
private:
    struct Register{
        Register(){
            QueryResult::registerFromJson("BusResult",&BusResult::fromJson);
        }
    };
    static Register s_register;
};

class CarResult:public QueryResult{
    QString Cnt;
    QString Price;
    static QueryResult* fromJson(const QJsonObject& json){
        CarResult* res = new CarResult();
        res->Destination = json["destination"].toString();
        res->Source = json["source"].toString();
        res->SetOutTime = QDateTime::fromString(json["starttime"].toString());
        res->ArriveTime = QDateTime::fromString(json["endtime"].toString());
        QStringList types = json["types"].toString().split(',');
        QStringList cnts = json["cnts"].toString().split(',');
        QStringList prices = json["prices"].toString().split(',');
        int index1 = types.indexOf("CarSeat");
        if(index1>=0){
            res->Cnt = cnts.at(index1);
            res->Price = prices.at(index1);
        }
        res->Id = json["name"].toString();
        return res;
    }
private:
    struct Register{
        Register(){
            QueryResult::registerFromJson("CarResult",&HighSpeedResult::fromJson);
        }
    };
    static Register s_register;
};
class RefundResult:public QueryResult{
public:
    QString orderId = "Test";
    QString trainname = "Test";
    QString orderTime = "Test";
    QString userId = "Test";
    QString price = "Test";
    static QueryResult* fromJson(const QJsonObject& json){
        RefundResult* res = new RefundResult();
        res->orderId = json["order_id"].toString();
        res->Id = json["train_id"].toString();
        res->trainname = json["train_name"].toString();
        res->price = json["ticket_price"].toString();
        res->SetOutTime = QDateTime::fromString(json["train_start_time"].toString());
        res->ArriveTime = QDateTime::fromString(json["train_start_time"].toString());
        res->userId = json["user_id"].toString();
        res->Source = json["from_station"].toString();
        res->Destination = json["to_station"].toString();
        res->orderTime= json["order_created_time"].toString();
        return res;
    }
private:
struct Register {
    Register() {
        QueryResult::registerFromJson("RefundResult", &FlightResult::fromJson);
    }
};
static Register s_register;
};

Q_DECLARE_METATYPE(QueryResult*);
Q_DECLARE_METATYPE(CarResult)
Q_DECLARE_METATYPE(BusResult)
Q_DECLARE_METATYPE(QuickTrainResult)
Q_DECLARE_METATYPE(HighSpeedResult)
Q_DECLARE_METATYPE(QueryResult)
Q_DECLARE_METATYPE(FlightResult)
Q_DECLARE_METATYPE(RefundResult)
#endif // QUERYRESULT_H
